其他
互联网大厂Java面试题集—Spring boot面试题(一)
Spring Boot 需要独立的容器运行吗?
可以不需要,内置了 Tomcat/ Jetty 等容器。通过pom.xml中导入依赖:
<!--spring-boot-starter-web:代表web模块,在这个模块中含了许多JAR包,--><!--有spring相关的jar,内置tomcat服务器,jackson等,这些web项目中常用的的功能都会自动引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot的核心注解是哪个?它主要由哪几个注解组成的?
启动类上面的注解是@SpringBootApplication
,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration
@EnableAutoConfiguration
:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
。
@ComponentScan
:Spring组件扫描。
如何理解Spring Boot中Starters含义?
Starters是什么?
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa
启动器依赖就能使用了。Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
Starters命名?
Spring Boot官方的启动器都是以spring-boot-starter-
命名的,代表了一个特定的应用类型。第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter
。
Starters分类:
1)Spring boot提供的启动器
4)其他第三方启动器(略)
Spring Boot实现热部署有哪几种方式?
在Spring Boot实现代码热部署是一件很简单的事情,代码的修改可以自动部署并重新热启动项目。
1)引用devtools依赖
<dependency><groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
修改一个java类时就可以实现热更新了。
2)自定义配置热部署
以下配置用于自定义配置热部署,可以不设置。
#热部署开关,false即不启用热部署
spring.devtools.restart,enabled: true#指定热部署的目录
#spring.devtools.restart.additional-paths: src/main/java#指定目录不更新
spring.devtools.restart.exclude: test/**3)Intellij Idea
工具修改实现热部署
需要改以下两个位置:
勾上自动编译或者手动重新编译
File > Settings > Compiler-Build Project automatically注册使用快捷键的方式:
ctrl + shift + alt + / > Registry > 勾选Compiler autoMake allow when app running注意事项:
1)生产环境devtools将被禁用,如java -jar
方式或者自定义的类加载器等都会识别为生产环境。
2)打包应用默认不会包含devtools,除非你禁用SpringBoot Maven
插件的excludeDevtools
属性。
3)Thymeleaf无需配置 spring.thymeleaf.cache:false
,devtools默认会自动设置,参考完整属性。
下面是devtools自动配置的完整源码:
@Order(Ordered.LOWEST_PRECEDENCE)public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostProcessor {
private static final Map<String, Object> PROPERTIES;
static {
Map<String, Object> devToolsProperties = new HashMap<>();
devToolsProperties.put("spring.thymeleaf.cache", "false");
devToolsProperties.put("spring.freemarker.cache", "false");
devToolsProperties.put("spring.groovy.template.cache", "false");
devToolsProperties.put("spring.mustache.cache", "false");
devToolsProperties.put("server.servlet.session.persistent", "true");
devToolsProperties.put("spring.h2.console.enabled", "true");
devToolsProperties.put("spring.resources.cache.period", "0");
devToolsProperties.put("spring.resources.chain.cache", "false");
devToolsProperties.put("spring.template.provider.cache", "false");
devToolsProperties.put("spring.mvc.log-resolved-exception", "true");
devToolsProperties.put("server.servlet.jsp.init-parameters.development", "true");
devToolsProperties.put("spring.reactor.stacktrace-mode.enabled", "true");
PROPERTIES = Collections.unmodifiableMap(devToolsProperties);
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
if (isLocalApplication(environment) && canAddProperties(environment)) {
PropertySource<?> propertySource = new MapPropertySource("refresh",
PROPERTIES);
environment.getPropertySources().addLast(propertySource);
}
}
private boolean isLocalApplication(ConfigurableEnvironment environment) {
return environment.getPropertySources().get("remoteUrl") == null;
}
private boolean canAddProperties(Environment environment) {
return isRestarterInitialized() || isRemoteRestartEnabled(environment);
}
private boolean isRestarterInitialized() {
try {
Restarter restarter = Restarter.getInstance();
return (restarter != null && restarter.getInitialUrls() != null);
}
catch (Exception ex) {
return false;
}
}
private boolean isRemoteRestartEnabled(Environment environment) {
return environment.containsProperty("spring.devtools.remote.secret");
}
}
4)devtools会在windows资源管理器占用java进程,在开发工具里面杀不掉,只能手动kill掉,不然重启会造成端口重复绑定报错。
Spring Boot如何定义多套不同环境配置?
简单来说,Profile就是Spring Boot可以对不同环境或者指令来读取不同的配置文件。
假如有开发、测试、生产三个不同的环境,需要定义三个不同环境下的配置。
1)基于properties文件类型可以另外建立3个环境下的配置文件:
applcation.propertiesapplication-dev.properties
application-test.properties
application-prod.properties
然后在applcation.properties
文件中指定当前的环境spring.profiles.active=test
,这时候读取的就是application-test.properties
文件。
2)基于yml文件类型,只需要一个applcation.yml文件即可,推荐此方式。
spring:profiles:
active: prod
---
spring:
profiles: dev
server:
port: 8080
---
spring:
profiles: test
server:
port: 8081
---
spring.profiles: prod
spring.profiles.include:
- proddb
- prodmq
server:
port: 8082
---
spring:
profiles: proddb
db:
name: mysql
---
spring:
profiles: prodmq
mq:
address: localhost
其中dev代表开发,test代表测试,prod代表正式环境。此时读取的就是prod的配置,prod包含proddb,prodmq,此时可以读取proddb,prodmq下的配置。也可以同时激活三个配置,如下:
spring.profiles.active: prod,proddb,prodmq3)基于Java代码,在JAVA配置代码中也可以加不同Profile下定义不同的配置文件,@Profile
注解只能组合使用@Configuration
和@Component
注解。
@Profile("prod")
public class ProductionConfiguration {
// ...
}
4)指定Profile
main方法启动方式:在Eclipse Arguments
里面添加
插件启动方式:
spring-boot:run -Drun.profiles=prodjar运行方式:
java -jar xx.jar --spring.profiles.active=prod除了在配置文件和命令行中指定Profile,还可以在启动类中写死指定,通过SpringApplication.setAdditionalProfiles
方法。
public void setAdditionalProfiles(String... profiles) {
this.additionalProfiles = new LinkedHashSet<String>(Arrays.asList(profiles));
}
推荐阅读
ActiveMQ消息队列从入门到实践(1)—JMS的概念和JMS消息模型
ActiveMQ消息队列从入门到实践(2)—Windows安装activemq服务
ActiveMQ消息队列从入门到实践(3)—通过ActiveMQ收发消息
ActiveMQ消息队列从入门到实践(4)—使用Spring JMS收发消息
JDK1.7中HashMap死环问题及JDK1.8中对HashMap的优化源码详解
Shiro应用篇(二):Shiro结合Redis实现分布式环境下的Session共享
微框架Spring Boot使用Redis如何实现Session共享
Java面试高级篇—Dubbo与Zookeeper面试题16期
Java面试高级篇—Java NIO:浅析I/O模型面试题15期
关注微信公众号“Java精选”(w_z90110),回复关键字领取资料:如Hadoop,Dubbo,CAS源码等等,免费领取资料视频和项目。
涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。